package com.xbongbong.workflow.service.strategy.data.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.product.pojo.dto.CostRecalculationDTO;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CostAdjustProductEntity;
import com.xbongbong.saas.domain.entity.ext.CostAdjustEntityExt;
import com.xbongbong.saas.enums.StockTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CostAdjustEnum;
import com.xbongbong.saas.help.ReceivablesHelper;
import com.xbongbong.saas.help.workflow.CostAdjustHelp;
import com.xbongbong.saas.model.CostAdjustModel;
import com.xbongbong.saas.model.CostAdjustProductModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.service.strategy.data.AbstractWorkflowDataStrategy;
import com.xbongbong.workflow.service.strategy.data.WorkflowDataProcessStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author WuHB
 * @date 2021/12/22 19:49
 */
@Service("workflowCostAdjustStrategy")
public class WorkflowCostAdjustStrategy extends AbstractWorkflowDataStrategy implements WorkflowDataProcessStrategy {

    private static final Logger LOG = LoggerFactory.getLogger(WorkflowCostAdjustStrategy.class);

    @Resource
    private CostAdjustModel costAdjustModel;

    @Resource
    private CostAdjustHelp CostAdjustHelp;

    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;

    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;

    @Resource
    private CostAdjustProductModel costAdjustProductModel;

    @Resource
    private ReceivablesHelper receivablesHelper;

    /**
     * 工作流数据操作策略类型
     *
     * @return 成本调整单类型
     */
    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.COST_ADJUST.getCode());
    }

    /**
     * 数据保存，工作流结束后操作
     *
     * @param workflowTransferPOJO      工作流转换
     * @param saasNeedRedundantAttrPojo saas节点字段
     * @throws XbbException 异常
     */
    @Override
    public void save(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜
        super.saveDataCabinetFile(workflowTransferPOJO);
        String corpid = workflowTransferPOJO.getCorpid();
        Data pojoData = workflowTransferPOJO.getData();
        JSONObject data = pojoData.getData();
        Long dataId = pojoData.getId();
        Long formId = pojoData.getFormId();
        CostAdjustEntityExt costAdjustEntityExt = costAdjustModel.getByKey(dataId, corpid);
        costAdjustEntityExt.setData(data);
        JSONArray productJsonArray = data.getJSONArray(CostAdjustEnum.PRODUCT.getAttr());
        String productStr = productJsonArray.toJSONString();
        CostAdjustHelp.addUpdateStock(productJsonArray, corpid, dataId, formId);
        data.put(CostAdjustEnum.PRODUCT.getAttr(), productJsonArray);

        //发送重算消息
        CostRecalculationDTO costRecalculationDTO = new CostRecalculationDTO();
        SaasFormSaveDTO saasFormSaveDTOCost = new SaasFormSaveDTO();
        saasFormSaveDTOCost.setCorpid(corpid);
        saasFormSaveDTOCost.setBusinessType(pojoData.getBusinessType());
        saasFormSaveDTOCost.setNewData(data);
        saasFormSaveDTOCost.setNewPaasFormDataEntity(costAdjustEntityExt);
        costRecalculationDTO.setType(StockTypeEnum.ADJUST_STOCK.getCode());
        costRecalculationDTO.setData(data);
        costRecalculationDTO.setStockId(dataId);
        costRecalculationDTO.setCorpid(corpid);
        costRecalculationDTO.setMark(BasicConstant.ONE);
        costRecalculationDTO.setIsWorkFlow(BasicConstant.ZERO);
        costRecalculationDTO.setSaasFormSaveDTO(saasFormSaveDTOCost);
        //将流水放至重算方法中生成，保证处理的先后顺序
        /*stockFlowBillHelp.caculateStockModification4Save(corpid, pojoData.getBusinessType(), data, costAdjustEntityExt);
        batchFlowBillHelp.batchFlowModification4Save(corpid, pojoData.getBusinessType(), data, costAdjustEntityExt);*/
        receivablesHelper.costRecalculationWorkFlow(costRecalculationDTO);
        addLinkDataDynamic(workflowTransferPOJO);
        // api
        super.apiHook(workflowTransferPOJO);
        // log
        afterSaveLog(workflowTransferPOJO);
    }

    /**
     * 数据编辑，工作流结束后操作
     *
     * @param workflowTransferPOJO      工作流转换
     * @param saasNeedRedundantAttrPojo saas节点字段
     * @throws XbbException 异常
     */
    @Override
    public void update(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜
        super.saveDataCabinetFile(workflowTransferPOJO);
        // api
        super.apiHook(workflowTransferPOJO);
        // log
        afterUpdateLog(workflowTransferPOJO);
    }

    /**
     * 数据编辑进工作流，拒绝后操作
     *
     * @param taskId               任务ID
     * @param workflowTransferPOJO 工作流转换
     * @throws XbbException 异常
     */
    @Override
    public void updateBack(Long taskId, WorkflowTransferPOJO workflowTransferPOJO) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Long backupDataId = workflowTransferPOJO.getBackupDataId();
            Long dataId = workflowTransferPOJO.getData().getId();
            WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(backupDataId, corpid);
            if (Objects.nonNull(workflowBackupDataEntity)) {
                JSONObject data = workflowBackupDataEntity.getData();

                replenishAttrForBackupData(workflowTransferPOJO.getData().getData(), data);

                CostAdjustEntityExt costAdjustEntityExt = new CostAdjustEntityExt();
                costAdjustEntityExt.setId(dataId);
                costAdjustEntityExt.setCorpid(corpid);
                costAdjustEntityExt.setData(data);
                costAdjustEntityExt.setSerialNo(data.getString(FieldTypeEnum.SERIALNO.getAlias()));
                // 获取负责人
                costAdjustEntityExt.setOwnerId(getOwnerId(data));
                costAdjustEntityExt.setDepartmentId(data.getLong(FieldTypeEnum.DEPARTMENTID.getAlias()));

                FormDataUtil.removeSystemData(data);
                // 这是修复线上已有的数据
                data.remove(StringConstant.PRODUCT);
                if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.UPDATE.getType())) {
                    costAdjustEntityExt.setFlowStatus(FlowStatusEnum.PASS.getType());
                }
                costAdjustModel.update(costAdjustEntityExt);
                // 回退被删掉的子表单
                updateBackSubForm(costAdjustEntityExt, corpid, IndexTypeEnum.IDX_SAAS_COST_ADJUST_SUB);
                //回退被删掉的富文本
                updateBackRichText(taskId, workflowTransferPOJO);
            }
        } catch (Exception e) {
            LOG.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowCostAdjustStrategy.updateBack error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    /**
     * 审批不通过（拒绝，撤回）
     *
     * @param taskId               任务ID
     * @param workflowTransferPOJO 工作流转换
     * @param taskType             任务类型
     * @throws XbbException 异常
     */
    @Override
    public void approvalFailed(Long taskId, WorkflowTransferPOJO workflowTransferPOJO, Integer taskType) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Data workflowData = workflowTransferPOJO.getData();
            Long dataId = workflowData.getId();
            Long formId = workflowData.getFormId();
            Integer businessType = workflowData.getBusinessType();
            Integer saasMark = workflowData.getSaasMark();
            CostAdjustEntityExt costAdjustEntityExt = new CostAdjustEntityExt();
            costAdjustEntityExt.setId(dataId);
            if (Objects.equals(TaskTypeEnum.REVOKE.getType(), taskType)) {
                costAdjustEntityExt.setFlowStatus(FlowStatusEnum.REVOKE.getType());
            } else {
                costAdjustEntityExt.setFlowStatus(FlowStatusEnum.REJECT.getType());
            }
            costAdjustEntityExt.setCorpid(corpid);
            costAdjustEntityExt.setUpdateTime(DateTimeUtil.getInt());
            costAdjustModel.update(costAdjustEntityExt);
            // 子表单
            DelEnum del = DelEnum.APPROVE_FAILED;

            paasFormSubDataModel.deleteBatchByDataId(Collections.singletonList(dataId), corpid, IndexTypeEnum.IDX_SAAS_INSTOCK_SUB, del);
            //富文本
            deleteFormRichText(dataId, corpid, formId, businessType, saasMark, DelEnum.NORMAL);

            // 关联产品
            List<CostAdjustProductEntity> productList = costAdjustProductModel.getProductsByAdjustIdIn(corpid, Arrays.asList(dataId));
            if (CollectionsUtil.isNotEmpty(productList)) {
                List<Long> idIn = new ArrayList<>();
                productList.forEach(item -> idIn.add(item.getId()));
                costAdjustProductModel.deleteBatchById(idIn, corpid, del.getDel());
            }
        } catch (Exception e) {
            LOG.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowCostAdjustStrategy.approvalFailed error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }
}
